﻿/*
 * Copyright 2011 Edward L. Stauff.                           Contact: <EdStauff@gmail.com>.
 * 
 * This file, "XerialMapping.cs", is part of the "Stauffware.Common.Xml.Xerialization" 
 * library.  "Stauffware.Common.Xml.Xerialization" is free software: you can redistribute 
 * it and/or modify it under the terms of the GNU Lesser Public License as published by 
 * the Free Software Foundation, either version 3 of the License, or (at your option) 
 * any later version.
 * 
 * "Stauffware.Common.Xml.Xerialization" is distributed in the hope that it will be 
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Public License for more 
 * details.
 * 
 * You should have received a copy of the GNU Lesser Public License along with 
 * "Stauffware.Common.Xml.Xerialization".  If not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Collections.Generic;
using System.Xml;
using System.Text;
using Stauffware.Common.Core;

namespace Stauffware.Common.Xml.Xerialization
{
	/// <summary>
	/// Contains shared stuff for XerialTypeMapping and XerialMemberMapping.
	/// </summary>
	public abstract class XerialMapping
	{
		/// <summary>
		/// The default name to use for the XML attribute or element.
		/// This will never be null.
		/// </summary>
		public readonly string XmlName;

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="xmlName">
		///		The default XML attribute name or element name.  Must not be null.
		/// </param>
		protected XerialMapping (string xmlName)
		{
			Require.NotNull(xmlName);
			string err = XmlUtils.ValidateXmlName(xmlName);
			if (err != null)
				throw new InputRequirement("\"" + xmlName + "\" is not a valid XML name; " + err);
			this.XmlName = xmlName;
		}

		/// <summary>
		/// The XerialContext to which this mapping belongs.  This will never be null.
		/// </summary>
		protected abstract XerialContext Context { get; }

		#region debugging stuff

		/// <summary>
		/// Returns whether the debug log is enabled.
		/// </summary>
		protected bool DebugLogEnabled { get { return this.Context.DebugLog != null; } }

		//-----------------------------------------------------------------------------
		/// <summary>
		/// Logs a method call.
		/// </summary>

		protected void LogCall (string methodName, params string[] args)
		{
			this.Context.DebugLog.Write(this.GetType().Name + "<" + this.XmlName + ">." + methodName + "(");
			for (int i = 0; i < args.Length; i++)
			{
				if (i > 0) this.Context.DebugLog.Write(", ");
				this.Context.DebugLog.Write(args[i]);
			}

			this.Context.DebugLog.WriteLine(")");
		}

		//-----------------------------------------------------------------------------
		/// <summary>
		/// Logs a method call, along with the current position of a NiceXmlReader.
		/// </summary>

		protected void LogCall (string methodName, NiceXmlReader rdr)
		{
			this.Context.DebugLog.Write(this.GetType().Name + "<" + this.XmlName + ">." + 
								methodName + "(" + rdr.NodeType.ToString());
			if (!string.IsNullOrEmpty(rdr.Name))
				this.Context.DebugLog.Write(" \"" + rdr.Name + "\"");
			this.Context.DebugLog.WriteLine(")");
		}

		//-----------------------------------------------------------------------------
		/// <summary>
		/// Writes a line of debugging output, including the current position of a
		/// NiceXmlReader.
		/// </summary>

		protected void LogLine (string prefix, NiceXmlReader rdr)
		{
			this.Context.DebugLog.Write(prefix + " " + rdr.NodeType.ToString());
			if (!string.IsNullOrEmpty(rdr.Name))
				this.Context.DebugLog.Write(" \"" + rdr.Name + "\"");
			this.Context.DebugLog.WriteLine(")");
		}

		//-----------------------------------------------------------------------------
		/// <summary>
		/// Writes a line of debugging output.
		/// </summary>

		protected void LogLine (string str)
		{
			this.Context.DebugLog.WriteLine(str);
		}

		//-----------------------------------------------------------------------------
		/// for debugging

		public override string ToString ()
		{
			return this.GetType().FullName + " " + CharEncoding.ToCsharpLiteral(this.XmlName); 
		}

		//-----------------------------------------------------------------------------

		#endregion

	}
}
